package com.songcha.library_business.proxy.configuration

import com.google.gson.Gson
import com.google.gson.JsonObject
import com.songcha.library_business.api.ApiManager
import com.songcha.library_business.bean.advert.AdvertInfoBean
import com.songcha.library_business.bean.configuration.AppVersionBean
import com.songcha.library_business.bean.configuration.SystemConfigurationBean
import com.songcha.library_business.bean.configuration.SystemConfigurationResultBean
import com.songcha.library_business.bean.configuration._SystemConfigurationDataBean
import com.songcha.library_business.config.FunctionConfig
import com.songcha.library_business.config.VarConfig
import com.songcha.library_common.LibraryCommon
import com.songcha.library_common.util.PackageUtil
import com.songcha.library_common.util.ToastUtil
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.schedulers.Schedulers
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable

/***
 * system global configuration
 */
class SystemConfigurationManager {
    companion object{
        @Volatile
        private var systemConfiguration:SystemConfigurationResultBean?=null

        @JvmStatic
        fun getSystemConfiguration(): Observable<SystemConfigurationResultBean> {
            if(systemConfiguration == null) {
                synchronized(SystemConfigurationManager::class.java){
                    if(systemConfiguration == null){
                        val obs=Observable.create<SystemConfigurationResultBean> {
                            ApiManager.api_timeout15.getSystemConfiguration()
                                .subscribeOn(Schedulers.io())
                                .observeOn(AndroidSchedulers.mainThread())
                                .map {it->
                                    val systemControl = it.data.systemControl
                                    val advertState = handleAppStartConfiguration(systemControl,1,"true").toBoolean()
                                    val vipState = handleAppStartConfiguration(systemControl,2,"true").toBoolean()
                                    val wxLoginState = handleAppStartConfiguration(systemControl,11,"true").toBoolean()
                                    val wxPayLoginState = handleAppStartConfiguration(systemControl,12,"true").toBoolean()

                                    //VarConfig.ADVERT_SPLASH_TYPE = handleAppStartConfiguration(systemControl,13,"0").toInt()
                                    //VarConfig.ADVERT_READER_BANNER_TYPE = handleAppStartConfiguration(systemControl,14,"0").toInt()
                                    //VarConfig.ADVERT_TASK_REWARD_TYPE = handleAppStartConfiguration(systemControl,15,"0").toInt()
                                    //deprecated
                                    //val advertReaderChapterLastXxlType = handleAppStartConfiguration(systemControl,16,"0").toInt()
                                    //VarConfig.ADVERT_READER_CHAPTER_LAST_XXL_PRIMARY_TYPE = handleAppStartConfiguration(systemControl,17,"0").toInt()
                                    //VarConfig.ADVERT_BOOK_SHELF_BANNER_TYPE = handleAppStartConfiguration(systemControl,18,"0").toInt()
                                    //VarConfig.ADVERT_READER_CHAPTER_LAST_REWARD_TYPE = handleAppStartConfiguration(systemControl,19,"0").toInt()
                                    //VarConfig.ADVERT_HOME_INSERT_SCREEN_TYPE = handleAppStartConfiguration(systemControl,20,"0").toInt()
                                    //VarConfig.ADVERT_HOME_XXL_TYPE = handleAppStartConfiguration(systemControl,21,"0").toInt()

                                    val privacyPolicy = handleAppStartConfiguration(systemControl,100,"")
                                    val userProtocol = handleAppStartConfiguration(systemControl,101,"")
                                    val vipProtocol = handleAppStartConfiguration(systemControl,102,"")
                                    val versionInfo = handleAppStartConfiguration(systemControl,200,"")
                                    var appVersionBean:AppVersionBean?=null
                                    if(versionInfo.isNotBlank()){
                                        appVersionBean = Gson().fromJson(versionInfo, AppVersionBean::class.java)
                                    }
                                    val customerService = handleAppStartConfiguration(systemControl,201,"")

                                    val advertCodeIds = handleAppStartConfiguration(systemControl,203,"")

                                    val advertAllType = handleAppStartConfiguration(systemControl,204,"-1").toInt()

                                    val readerBannerAdvertCountDown = handleAppStartConfiguration(systemControl,205,"60").toInt()

                                    if(advertCodeIds.isNotBlank()){
                                        try{
                                            val advertCodeIdsObj = Gson().fromJson(advertCodeIds.replace("\r\n","").replace("\n",""),
                                                JsonObject::class.java)
                                            VarConfig.ADVERT_APP_ID_CSJ = getJsonObjString(advertCodeIdsObj,"appid","csj")
                                            VarConfig.ADVERT_APP_ID_GDT = getJsonObjString(advertCodeIdsObj,"appid","gdt")
                                            VarConfig.ADVERT_SPLASH_INFO = Gson().fromJson(getJsonObjString(advertCodeIdsObj,"splash"),AdvertInfoBean::class.java)
                                            VarConfig.ADVERT_READER_BANNER_INFO = Gson().fromJson(getJsonObjString(advertCodeIdsObj,"reader_banner"),AdvertInfoBean::class.java)
                                            VarConfig.ADVERT_READER_CHAPTER_XXL_INFO = Gson().fromJson(getJsonObjString(advertCodeIdsObj,"reader_chapter_xxl"),AdvertInfoBean::class.java)
                                            VarConfig.ADVERT_READER_CHAPTER_REWARD_INFO = Gson().fromJson(getJsonObjString(advertCodeIdsObj,"reader_chapter_reward"),AdvertInfoBean::class.java)
                                            VarConfig.ADVERT_TASK_REWARD_INFO = Gson().fromJson(getJsonObjString(advertCodeIdsObj,"task_reward"),AdvertInfoBean::class.java)
                                            VarConfig.ADVERT_BOOK_SHELF_BANNER_INFO = Gson().fromJson(getJsonObjString(advertCodeIdsObj,"book_shelf_banner"),AdvertInfoBean::class.java)
                                            VarConfig.ADVERT_HOME_INSERT_SCREEN_INFO = Gson().fromJson(getJsonObjString(advertCodeIdsObj,"home_insert_screen"),AdvertInfoBean::class.java)
                                            VarConfig.ADVERT_HOME_BANNER_INFO = Gson().fromJson(getJsonObjString(advertCodeIdsObj,"home_banner"),AdvertInfoBean::class.java)
                                            VarConfig.ADVERT_CATEGORY_BANNER_INFO = Gson().fromJson(getJsonObjString(advertCodeIdsObj,"category_banner"),AdvertInfoBean::class.java)
                                            VarConfig.ADVERT_TASK_BANNER_INFO = Gson().fromJson(getJsonObjString(advertCodeIdsObj,"task_banner"),AdvertInfoBean::class.java)
                                            VarConfig.ADVERT_TASK_INSERT_SCREEN_INFO = Gson().fromJson(getJsonObjString(advertCodeIdsObj,"task_insert_screen"),AdvertInfoBean::class.java)
                                            VarConfig.ADVERT_MINE_BANNER_INFO = Gson().fromJson(getJsonObjString(advertCodeIdsObj,"mine_banner"),AdvertInfoBean::class.java)

                                            if(advertAllType > -1){
                                                VarConfig.ADVERT_SPLASH_INFO.type = advertAllType
                                                VarConfig.ADVERT_READER_BANNER_INFO.type = advertAllType
                                                VarConfig.ADVERT_READER_CHAPTER_XXL_INFO.type = advertAllType
                                                VarConfig.ADVERT_READER_CHAPTER_REWARD_INFO.type = advertAllType
                                                VarConfig.ADVERT_TASK_REWARD_INFO.type = advertAllType
                                                VarConfig.ADVERT_BOOK_SHELF_BANNER_INFO.type = advertAllType
                                                VarConfig.ADVERT_HOME_INSERT_SCREEN_INFO.type = advertAllType
                                                VarConfig.ADVERT_HOME_BANNER_INFO.type = advertAllType
                                                VarConfig.ADVERT_CATEGORY_BANNER_INFO.type = advertAllType
                                                VarConfig.ADVERT_TASK_BANNER_INFO.type = advertAllType
                                                VarConfig.ADVERT_TASK_INSERT_SCREEN_INFO.type = advertAllType
                                                VarConfig.ADVERT_MINE_BANNER_INFO.type = advertAllType
                                            }
                                        }catch (e:Exception){
                                            e.printStackTrace()
                                        }
                                    }

                                    FunctionConfig.IS_ADVERT_ENABLED = advertState
                                    FunctionConfig.IS_VIP_ENABLED = vipState
                                    FunctionConfig.IS_WX_LOGIN_ENABLED = wxLoginState
                                    FunctionConfig.IS_WX_PAY_ENABLED = wxPayLoginState

                                    VarConfig.ADVERT_READER_BANNER_ADVERT_COUNTDOWN = readerBannerAdvertCountDown


                                    return@map SystemConfigurationResultBean(advertState,userProtocol,privacyPolicy,vipProtocol,appVersionBean,customerService)
                                }
                                .subscribe(object : Observer<SystemConfigurationResultBean>{
                                    override fun onSubscribe(d: Disposable) {
                                        //if already instantiate,then cancel
                                        if(systemConfiguration!=null){
                                            d.dispose()
                                        }
                                    }

                                    override fun onError(e: Throwable) {
                                        it.onError(e)
                                    }

                                    override fun onComplete() {

                                    }

                                    override fun onNext(t: SystemConfigurationResultBean) {
                                        systemConfiguration=t
                                        it.onNext(t)
                                        it.onComplete()
                                    }

                                })

                        }
                        return obs
                    }
                }
            }
            return Observable.just(systemConfiguration!!)

        }

        @JvmStatic
        private fun getJsonObjString(jsonObject: JsonObject,type:String,key:String? = null):String{
            try{
                    if(jsonObject.has(type)){
                        val obj = jsonObject.get(type).asJsonObject
                        if(key != null && obj.has(key))
                            return obj.get(key).asString
                        else
                            return obj.toString()
                    }
            }catch (e:Exception){
                e.printStackTrace()
            }
            return ""
        }

        @JvmStatic
        private fun handleAppStartConfiguration(list:MutableList<SystemConfigurationBean.DataBean.SystemControlBean>, type:Int, defaultValue:String):String{
            //if version or packageName is null that adapt all version or packageName
            val channel = PackageUtil.getUmengChannelName(LibraryCommon.getContext())
            val version = PackageUtil.getPackageVersionName(LibraryCommon.getContext())
            var channelList = mutableListOf<SystemConfigurationBean.DataBean.SystemControlBean>()
            val nullChannelList = mutableListOf<SystemConfigurationBean.DataBean.SystemControlBean>()
            var versionList = mutableListOf<SystemConfigurationBean.DataBean.SystemControlBean>()
            val nullVersionList = mutableListOf<SystemConfigurationBean.DataBean.SystemControlBean>()
            val packageName = PackageUtil.getPackageName(LibraryCommon.getContext())
            var packageList = mutableListOf<SystemConfigurationBean.DataBean.SystemControlBean>()
            val nullPackageList = mutableListOf<SystemConfigurationBean.DataBean.SystemControlBean>()

            //priority:packageName>version>channel

            //find packageName
            for(i in 0 until list.size){
                val item = list[i]
                if(item.type != type) continue
                if(item.packageName.isNullOrEmpty()){
                    nullPackageList.add(item)
                }else if(item.packageName == packageName){
                    packageList.add(item)
                }
            }
            //set package
            if(nullPackageList.size > 0){
                packageList.addAll(nullPackageList)
            }

            //find version
            for(i in 0 until packageList.size){
                val item = packageList[i]
                if(item.type != type) continue
                if(item.version.isNullOrEmpty()){
                    nullVersionList.add(item)
                }else if(item.version == version){
                    versionList.add(item)
                }
            }
            //set version
            if(nullVersionList.size > 0){
                versionList.addAll(nullVersionList)
            }

            //find channel
            for(i in 0 until versionList.size){
                val item = versionList[i]
                if(item.type != type) continue
                if(item.channel.isNullOrEmpty()){
                    nullChannelList.add(item)
                }else if(item.channel == channel){
                    channelList.add(item)
                }
            }
            //set channel
            if(nullChannelList.size > 0){
                channelList.addAll(nullChannelList)
            }

            if(channelList.size == 0) return defaultValue

            try{
                return channelList[0].configuration?:""
            }catch (e:Exception){
                e.printStackTrace()
            }

            return defaultValue
        }

    }
}